package com.arcsoft.crud.limitNumber.base;

import java.util.Date;

import com.arcsoft.crud.base.TaskBase;

public abstract class BenchmarkTask extends TaskBase {

	protected BenchmarkBase parent;
	protected long loopCount;

	public BenchmarkTask(int threadIndex, BenchmarkBase parent, int printInfoInterval, long loopCount, String taskLogTable) {
		super (printInfoInterval, taskLogTable, threadIndex);
		this.parent = parent;
		this.loopCount = loopCount;
	}

	@Override
	public void run() {
		onThreadStart();
		Date threadStartDate = new Date();
		try {
			for (int i = 0; i < loopCount; i++) {
				Date startDate = new Date();
				try{
					String requestDetail = execute(i);
					Date endDate = new Date();
					logInfo(startDate, endDate,requestDetail,new Long(endDate.getTime()-startDate.getTime()).intValue());
					printInfo(i,threadStartDate);
				}catch(Exception e){
					logInfo(startDate, new Date(), e.toString(), 0);
				}
			}
		}finally {
			onThreadFinish();
		}
	}
	
	/**
	 * Must be invoked after each thread finish the prepare job, return the startTime. 
	 */
	protected void onThreadStart() {
		parent.startLock.countDown();
		//wait for all other threads ready
		try {
			parent.startLock.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		startTime = new Date();
	}
	
	/**
	 * Must be invoked after the loop in thread finish.
	 */
	protected void onThreadFinish() {
		System.out.printf("Thread %02d finish.\n", threadIndex);
		parent.finishLock.countDown();
	}
	
	public abstract String execute(int loopIndex);
}